/* eslint-disable dot-notation */
/* eslint-disable no-unused-vars */
/* eslint-disable operator-assignment */
/* eslint-disable no-param-reassign */
/* eslint-disable no-shadow-restricted-names */
/* eslint-disable prefer-const */
/* eslint-disable no-restricted-syntax */
(() => {
    const debounceList = ["click"];
    const blackList = ["#comment", "#text", "SCRIPT", "BODY", "STYLE"];
    const wait = 1000;
    const o = addEventListener;

    function rewriteEventListener(el) {
        // console.dir('el - ');
        // console.dir(el);
        // console.dir('  ');
        // ADD EVENT
        try {
            el.addEventListener = (type, func, options) => {
                if (debounceList.includes(type)) {
                    const funcO = func;
                    func = (...arguments) => {
                        if (el.__debounce_timer__) {
                            clearTimeout(el.__debounce_timer__);
                        }
                        el.__debounce_timer__ = setTimeout(() => {
                            funcO(...arguments);
                        }, wait);
                    };
                }

                return o(type, func, options);
            };
        } catch (err) {
            console.warn(err);
        }

        // onclick
        try {
            const invoker = el.onclick;
            if (invoker) {
                el.onclick = (...arguments) => {
                    if (el.__debounce_timer__) {
                        clearTimeout(el.__debounce_timer__);
                    }
                    el.__debounce_timer__ = setTimeout(() => {
                        invoker(...arguments);
                    }, wait);
                };
            }
        } catch (error) {
            console.warn(error);
            // console.dir('==== ');
            // console.dir(el);
            // console.dir('==== ');
        }
        // VUE
        try {
            if (
                window.__VUE__ &&
                el._vei &&
                el._vei.onClick &&
                el._vei.onClick.value
            ) {
                const invoker = el._vei.onClick.value;
                el._vei.onClick.value = (...arguments) => {
                    if (el.__debounce_timer__) {
                        clearTimeout(el.__debounce_timer__);
                    }
                    el.__debounce_timer__ = setTimeout(() => {
                        invoker(...arguments);
                    }, wait);
                };
            }
        } catch (error) {
            console.warn(error);
            // console.dir('==== ');
            // console.dir(el);
            // console.dir('==== ');
        }

        if (el.childNodes && el.childNodes.length > 0) {
            el.childNodes.forEach((item) => {
                if (!blackList.includes(item.nodeName)) {
                    rewriteEventListener(item);
                }
            });
        }
    }

    // 观察器的配置（需要观察什么变动）
    const config = { attributes: true, childList: true, subtree: true };

    // 当观察到变动时执行的回调函数
    const callback = function (mutationsList) {
        // Use traditional 'for loops' for IE 11
        for (let mutation of mutationsList) {
            if (mutation.type === "childList") {
                // console.log('A child node has been added or removed.', mutation);
                try {
                    const addNodeList = mutation.addedNodes;
                    addNodeList.forEach((element) => {
                        if (!blackList.includes(element.nodeName)) {
                            rewriteEventListener(element);
                        }
                    });
                } catch (error) {
                    console.warn(error);
                }
            }
        }
    };

    // 创建一个观察器实例并传入回调函数
    const observer = new MutationObserver(callback);

    // 以上述配置开始观察目标节点
    observer.observe(document, config);

    window.addEventListener("beforeunload", () => {
        observer.disconnect();
    });
})(window);
